package sim;

import sim.framework.*;
import sim.pref.*;
import sim.framework.io.*;
import sim.framework.dialog.*;
import sim.framework.gui.*;
import sim.auth.*;

public final class ModInit extends Module implements FileGets {
    
    private static final int INSTALL_STATUS_CHECK = 1;
    private static final int INSTALL_STATUS_COPY = 2;
    
    private boolean m_Installing = false;
    private boolean m_Cancel = false;
    
    private int m_InstallStatus = ModInit.INSTALL_STATUS_CHECK;
    
    public ModInit(int i, Simlet s) {
        super(i, s);
    }
    
    public void work(final Msg msg) {
        switch (msg.getWParam()) {
	case Executable.STATE_INIT:
	    workInit(msg);
	    break;
	case Executable.STATE_NEXT:
	    workNext(msg);
	    break;
	case Executable.STATE_BACK:
	    m_Simlet.execFail(getLabel(Resource.LBL_FAIL_INITIALIZATION));
	    break;
        }
        
    }
    
    private void workInit(final Msg msg) {
        // Si Simlet no está instalado ...
        if (!isInstalled()) {
            if (installInit()) {
                // ... instalar
                if (install()) {
                    installLog(getLabel(Resource.LBL_MESG_INSTALLOK));
                }
                // Detener instalación
                installTerm();
                return;
            }
            // Salir si falló inciar instalación
            exec(createModule(Simlet.MOD_KILL));
            return;
        }
        // Leer configuración
        //m_Simlet.appCfgLoadFromFile();
        // Iniciar la carga
        todo(Executable.STATE_NEXT);
    }
    
    private void workNext(final Msg msg) {
        DocAuth docAuth;
        
        //#ifdef DEBUG_MODINIT
        //# System.out.println("ModInit::workNext() ENTERED");
        //#endif
        
        //#ifdef DEBUG_MODINIT
        //# System.out.println("\tComprobando carga preferencias ...");
        //#endif
        if (getDocument(Simlet.MOD_PREF) == null) {
            execQueue(this, this);
            exec(createModule(Simlet.MOD_PREF));
            return;
        }
        
        //#ifdef DEBUG_MODINIT
        //# System.out.println("\tComprobando autenticación remota ...");
        //#endif
        if (getDocument(Simlet.MOD_AUTH) == null) {
            execQueue(this, this);
            exec(createModule(Simlet.MOD_AUTH));
            return;
        }
        
        //#ifdef DEBUG_MODINIT
        //# System.out.println("\tComprobando autenticación local ...");
        //#endif
        docAuth = (DocAuth)getDocument(Simlet.MOD_AUTH);
        if (!docAuth.isAuthenticated()) {
            execQueue(this, this);
            exec(createModule(Simlet.MOD_PASS));
            return;
        }
        
        // Sincronización
	if (getDocument(Simlet.MOD_SYNC) == null) {
	    execQueue(this, this);
	    exec(createModule(Simlet.MOD_SYNC));
	    return;
	}
        
        // Inicialización completa
        m_Simlet.setInitOk();
        
        // Se ejecuta el contador de timeout
        m_Simlet.setTimeOut(getAppCfgTimeOut());
        
        // Ejecutar el shell
        exec(createModule(Simlet.MOD_SHEL));
        
        //#ifdef DEBUG_MODINIT
        //# System.out.println("ModInit::workNext() EXITING");
        //#endif
        
    }
    
    public boolean event(final Msg msg) {
        boolean ret = false;
        
        switch (msg.getEventCode()) {
	case EventListener.COMMAND:
            {
                switch (msg.getWParam()) {
		case Dialog.CTRL_BUTTON_NEXT:
		    if (m_Installing) {
			// Instalando ...
			//#ifdef DEBUG_MODINIT
			//# System.out.println("\tCancelando instalación ...");
			//#endif
			m_Cancel = true;
		    } else {
			// Instalado!
			//#ifdef DEBUG_MODINIT
			//# System.out.println("\tCerrando aplicación ...");
			//#endif
			exec(createModule(Simlet.MOD_KILL));
		    }
		    ret = true;
		    break;
                }
            }
        }
        
        return ret;
    }
    
    private boolean isInstalled() {
        FileStream file;
        boolean ret;
        
        //#ifdef DEBUG_MODINIT
        //# System.out.println("ModInit::isInstalled() ENTERED");
        //#endif
        
        ret = false;
        file = (FileStream)FileStream.create(m_Simlet, FileNames.FILE_INSTALL, File.MODE_READ);
        if (file != null) {
            // Comprobar que cada archivo especificado en el
            // archivo FileNames.FILE_INSTALL exista.
            m_InstallStatus = ModInit.INSTALL_STATUS_CHECK;
            file.gets(this);
            if (file.eof()) {
                ret = true;
            }
        }
        
        //#ifdef DEBUG_MODINIT
        //# if (ret)
        //# System.out.println("\tInstalado!");
        //# else
        //# System.out.println("\tNo instalado!");
        //#endif
        
        //#ifdef DEBUG_MODINIT
        //# System.out.println("ModInit::isInstalled() EXITING");
        //#endif
        
        return ret;
    }
    
    private boolean install() {
        boolean ret;
        FileStream file;
        
        //#ifdef DEBUG_MODINIT
        //# System.out.println("ModInit::install() ENTERED");
        //#endif
        
        m_InstallStatus = ModInit.INSTALL_STATUS_COPY;
        
        // Borrar el script de instalación
        File.delete(FileNames.FILE_INSTALL);
        
        ret = false;
        
        // Crear el indicador de instalación
        if (File.create(m_Simlet, "/" + FileNames.FILE_INSTALL, FileNames.FILE_INSTALL, File.TYPE_TXT)) {
            file = (FileStream)FileStream.create(m_Simlet, FileNames.FILE_INSTALL, File.MODE_READ);
            if (file != null) {
                // Instalar cada archivo especificado en el archivo FileNames.FILE_INSTALL
                file.gets(this);
                // Si no se llega al final del archivo ...
                if (!file.eof()) {
                    // ... algo falló, y todo no está instalado.
                    file.close();
                    File.delete(FileNames.FILE_INSTALL);
                } else {
                    file.close();
                    ret = true;
                }
            }
        }
        
        //#ifdef DEBUG_MODINIT
        //# if (ret)
        //# System.out.println("\tok!!");
        //# else
        //# System.out.println("\tfalló!");
        //#endif
        
        //#ifdef DEBUG_MODINIT
        //# System.out.println("ModInit::install() EXITING");
        //#endif
        
        return ret;
    }
    
    public boolean fileGetsLine(final byte[] line, int size, int crlf) {
        String filename;
        boolean ret;
        
        //#ifdef DEBUG_MODINIT
        //# System.out.println("ModInit::fileGetsLine() ENTERED");
        //#endif
        
        ret = true;
        if (size > crlf) {
            filename = new String(line, 0, size - crlf);
            
            switch(m_InstallStatus) {
	    case ModInit.INSTALL_STATUS_CHECK:
		//#ifdef DEBUG_MODINIT
		//# System.out.println("\tBuscando : " + filename);
		//#endif
		ret = File.exists(filename);
		break;
	    case ModInit.INSTALL_STATUS_COPY:
		//#ifdef DEBUG_MODINIT
		//# System.out.println("\tInstalando : " + filename);
		//#endif
		installLog(filename + "...");
		ret = File.create(m_Simlet, "/" + filename, filename, File.TYPE_TXT);
            }
            
            //#ifdef DEBUG_MODINIT
            //# System.out.println("ModInit::fileGetsLine() EXITING");
            //#endif
        }
        
        return (ret && !m_Cancel);
    }
    
    private boolean installInit() {
        DlgWarning dlg;
        // Registro de eventos.
        m_Installing = false;
        dlg = (DlgWarning)DlgWarning.create(m_Simlet,
					    getLabel(Resource.LBL_TITLE_APP), // título
					    null, // sin texto inicial
					    getLabel(Resource.LBL_CTRL_CANCEL), // quiero un boton que diga Cancela :-)
					    null); // sin boton atrás.
        if (dlg != null) {
            m_Installing = true;
            setGui(dlg);
	    //dlg.setProperties(Dialog.CTRL_MAIN, GuiCtrlPrompt.JUSTIFY_NONE);
        }
        return m_Installing;
    }
    
    private void installTerm() {
        DlgWarning dlg;
        dlg = (DlgWarning)getGui();
        m_Installing = false;
        dlg.setItemText( Dialog.CTRL_SOFTM, Dialog.CTRL_BUTTON_NEXT,
			 getLabel(Resource.LBL_CTRL_ACCEPT) );
    }
    
    private void installLog(final String message) {
        Gui dlg;
        dlg = getGui();
        dlg.addText(Dialog.CTRL_MAIN, dlg.getCount(Dialog.CTRL_MAIN), message);
        dlg.addText(Dialog.CTRL_MAIN, dlg.getCount(Dialog.CTRL_MAIN), "\n");
    }
    
}
